/**
 * @author QL
 * @date 2021-12-24 13:50:22
 * @version V..
 * @description 网络通信控制方法
 */
import NetInterface from './NetInterface.js'
// import jsencrypt from './otherJS/jsencrypt.min.js' // encrypt加密插件，需要后端配置同类加密解密方法，并提供密钥
import Axios from 'axios'
import Qs from 'qs'

class NetConnect extends NetInterface {
	constructor() {
		super()

		this.request = Axios.create();

		this.request.defaults.timeout = 5000;


		/**
		 * @author QL
		 * @functionName axios.interceptors.request.use
		 * @param { Function }  _beforeRequest(默认传入请求方法的配置对象)
		 * @param { Function }  _interceptorErr
		 * @date 2021-12-24 15:58:43
		 * @version V..
		 * @description 配置axios网络请求的前置拦截器
		 */
		this.request.interceptors.request.use(this._beforeRequest, this._interceptorErr);

		/**
		 * @author QL
		 * @functionName axios.interceptors.response.use
		 * @param { Function } _beforeResponse(默认传入网络响应体的对象)
		 * @param { Function } _interceptorErr  
		 * @date 2021-12-24 15:58:43
		 * @version V..
		 * @description 配置axios网络响应体的前置拦截器
		 */
		this.request.interceptors.response.use(this._beforeResponse, this._interceptorErr);
	}

	/**
	 * @author QL
	 * @functionName _beforeRequest
	 * @param { * } config 当前请求的配置对象
	 * @date 2021-12-24 13:50:37
	 * @version V..
	 * @description 发起请求的前置拦截器，用于请求前为请求添加配置属性或者参数设置
	 */
	_beforeRequest(config) {
		console.log("net--request（发起请求）前置拦截器:", config);
		// urlencoded 协议下，参数需要经过Qs方法转换为路由参数形式，即JSON格式
		if (config.headers['Content-Type'] && config.headers['Content-Type'] === "application/x-www-form-urlencoded") {
			config.data = Qs.stringify(config.data)

			if (config.method === 'get') {
				config.url = config.url + "?" + config.data;
			}
		}
		return config
	}

	/**
	 * @author QL
	 * @functionName _beforeResponse
	 * @param { * } response 响应返回的源数据
	 * @date 2021-12-24 13:51:21
	 * @version V..
	 * @description 收到响应数据then之前，拦截数据做一定的处理判断的方法
	 */
	_beforeResponse(response) {
		console.log("net--response（接收响应）前置拦截器:", response);
		return response
	}

	/**
	 * @author QL
	 * @functionName _interceptorErr
	 * @param { * } err  
	 * @date 2021-12-24 13:52:03
	 * @version V..
	 * @description 用于处理拦截器抛出的异常信息
	 */
	_interceptorErr(err) {
		console.log("net--接口服务抛出异常:", err);
		return Promise.reject(err)
	}

	/**
	 * @author QL
	 * @functionName netRequest
	 * @param { Object } baseicConfig
	 * @example 
	 * 	baseicConfig: {
	 * 	  method: 请求方式[GET, POST, FILE], 
	 * 	  IPPort: 服务端口别名, 
	 * 	  urlName: 接口路由别名, 
	 * 	  fileObj: 文件流对象, 
	 * 	  contentType: 头协议"Content-Type"的类型
	 * 	}
	 * @param { Object | Array } requestParams
	 * @date 2021-12-24 13:52:35
	 * @version V..
	 * @description 网络请求封装方法带token
	 */
	netRequest(baseicConfig, requestParams) {
		let _this = this;
		baseicConfig.method = baseicConfig.method.toUpperCase();
		let mUrl = this._getInterface(baseicConfig.IPPort, baseicConfig.urlName);
		this.utils.setConsole('转换后的method:', baseicConfig.method);
		this.utils.setConsole('url别名:', baseicConfig.urlName);
		this.utils.setConsole('url:', mUrl);
		this.utils.setConsole('token:', this.token);
		this.utils.setConsole('参数:', requestParams);

		if (baseicConfig.method === 'FILE') {
			let fileStream = new FormData();
			fileStream.append('file', baseicConfig.fileObj);
			return new Promise((resolve, reject) => {
				this.request({
					method: baseicConfig.method,
					url: mUrl,
					data: fileStream,
					headers: {
						'Authorization': 'Barea ' + this.token,
						'Content-Type': 'multipart/form-data'
					}
				}).then(res => {
					_this.utils.setConsole("请求成功res:", res);
					resolve(res);
				}).catch(err => {
					_this.utils.setConsole("err:", err);
					reject(err);
				})
			})
		} else {
			return new Promise((resolve, reject) => {
				this.request({
					method: baseicConfig.method,
					url: mUrl,
					data: requestParams,
					headers: {
						'Authorization': 'Barea ' + this.token,
						'Content-Type': baseicConfig.contentType
					}
				}).then(res => {
					_this.utils.setConsole("请求成功res:", res);
					resolve(res);
				}).catch(err => {
					_this.utils.setConsole("err:", err);
					reject(err);
				})
			})
		}
	}

	/**
	 * @author QL
	 * @functionName noToken
	 * @param { Object } baseicConfig
	 * @example 
	 * 	baseicConfig: {
	 * 	  method: 请求方式[GET, POST, FILE], 
	 * 	  IPPort: 服务端口别名, 
	 * 	  urlName: 接口路由别名, 
	 * 	  fileObj: 文件流对象, 
	 * 	  contentType: 头协议"Content-Type"的类型
	 * 	}
	 * @param { Object | Array } requestParams
	 * @date 2021-12-24 13:54:24
	 * @version V..
	 * @description 执行无token的网络请求
	 */
	noToken(baseicConfig, requestParams) {
		let _this = this;
		baseicConfig.method = baseicConfig.method.toUpperCase();
		let mUrl = this._getInterface(baseicConfig.IPPort, baseicConfig.urlName);
		this.utils.setConsole('转换后的method:', baseicConfig.method);
		this.utils.setConsole('url别名:', baseicConfig.urlName);
		this.utils.setConsole('url:', mUrl);
		this.utils.setConsole('token:', this.token);
		this.utils.setConsole('参数:', requestParams);

		if (baseicConfig.method === 'FILE') {
			let fileStream = new FormData();
			fileStream.append('file', baseicConfig.fileObj);
			return new Promise((resolve, reject) => {
				this.request({
					method: baseicConfig.method,
					url: mUrl,
					data: fileStream,
					headers: {
						'Content-Type': 'multipart/form-data'
					}
				}).then(res => {
					_this.utils.setConsole("请求成功res:", res);
					resolve(res);
				}).catch(err => {
					_this.utils.setConsole("err:", err);
					reject(err);
				})
			})
		} else {
			return new Promise((resolve, reject) => {
				this.request({
					method: baseicConfig.method,
					url: mUrl,
					data: requestParams,
					headers: {
						'Content-Type': baseicConfig.contentType
					}
				}).then(res => {
					_this.utils.setConsole("请求成功res:", res);
					resolve(res);
				}).catch(err => {
					_this.utils.setConsole("err:", err);
					reject(err);
				})
			})
		}
	}

	/**
	 * @author QL
	 * @functionName requestAll
	 * @param { Array } promiseList 
	 * @date 2021-12-24 13:55:32
	 * @version V..
	 * @description 触发多个promise方法异步执行过程，最终同步回收所有promise方法的结果
	 */
	requestAll(promiseList) {
		let _this = this;
		this.utils.setConsole("并发请求:", promiseList);
		return Promise.all(promiseList).then(res => {
			_this.utils.setConsole("promiseAll-res:", res);
			resolve(res);
		}).catch(err => {
			reject(err);
		})
	}

}
export default NetConnect
